package GUI.main.dialogs;

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;

import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.border.MatteBorder;

import officeserver.log_error.AppointmentException;
import officeserver.log_error.UserException;
import officeserver.report.Appointment;
import officeserver.users.PersonalInfo;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;

import GUI.calendar.CalendarPanel;
import GUI.helpers.ButtonType;
import GUI.helpers.PButton;
import GUI.helpers.ProjectConstants;
import GUI.main.MainClient;

/**
 * @author mramsey3
 *
 */
public class WeightChartDialog extends JDialog implements ActionListener {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private PersonalInfo pInfo;
    private JPanel titlePanel;
    private JPanel buttonPanel;
    private PButton closeButton;
    private CategoryDataset dataset;
    private JFreeChart chart;
    private ChartPanel chartPanel;
    
    private final static int WIDTH = 750;
    private final static int HEIGHT = 600;

    /**
     * @param pInfo
     */
    public WeightChartDialog(PersonalInfo pInfo) {
	setSize(new Dimension(750, 600));
	final Toolkit toolkit = Toolkit.getDefaultToolkit();
	final Dimension screenSize = toolkit.getScreenSize();
	final int x = (screenSize.width - WIDTH) / 2;
	final int y = (screenSize.height - HEIGHT) / 2;
	setLocation(x, y);
	this.pInfo = pInfo;
	setLayout(new BorderLayout());
	add(getChartPanel(), BorderLayout.CENTER);
	add(getTitlePanel(),BorderLayout.NORTH);
	add(getButtonPanel(),BorderLayout.SOUTH);
    }
    
    private ChartPanel getChartPanel(){
	if(chartPanel == null){
	    chartPanel = new ChartPanel(getChart());
	    chartPanel.setPreferredSize(new Dimension(WIDTH,500));
	    chartPanel.setBorder(new LineBorder(ProjectConstants.BORDER_SUB_COLOR,4));
	}
	return chartPanel;
    }
    
    private JFreeChart getChart(){
	if(chart == null){
	    chart = createChart(getDataset());
	}
	return chart;
    }

    private CategoryDataset getDataset(){
	if(dataset == null){
	    dataset = createDataset();
	}
	return dataset;
    }
    
    private JPanel getTitlePanel(){
	if (titlePanel == null) {
	    titlePanel = new JPanel() {
		private static final long serialVersionUID = 1L;

		public void paintComponent(Graphics g) {
		    super.paintComponent(g);
		    g.setColor(ProjectConstants.SUBHEADER_COLOR);
		    g.fillRect(0, 0, getWidth(), getHeight());
		    g.setColor(Color.white);
		    g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 18));
		    g.drawString(pInfo.getFirstName().toLowerCase()+" "+pInfo.getLastName().toLowerCase()+"'s weight", 12, getHeight() - 8);
		}
	    };
	    titlePanel.setPreferredSize(new Dimension(WIDTH, 50));
	}
	return titlePanel;
    }
    
    private JPanel getButtonPanel(){
	if(buttonPanel == null){
	    buttonPanel = new JPanel();
	    buttonPanel.setBorder(new EmptyBorder(10,20,10,10));
	    buttonPanel.add(getCloseButton());
	    
	}
	return buttonPanel;
    }
    
    private PButton getCloseButton(){
	if(closeButton == null){
	    closeButton = new PButton("close",ButtonType.MEDIUM);
	    closeButton.addActionListener(this);
	}
	return closeButton;
    }
    /**
     * @return
     */
    private CategoryDataset createDataset() {

	final String series1 = "Weight";
	final DefaultCategoryDataset dataset = new DefaultCategoryDataset();

	try {
	    MainClient.getConnection().userSearch(pInfo.getUsername());
	} catch (UserException e) {
	    e.printStackTrace();
	}
	ArrayList<Appointment> appointments = null;
	try {
	    appointments = MainClient.getConnection()
		    .getSearchUserAppointments();
	} catch (UserException e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	} catch (AppointmentException e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	}

	for (Appointment appt : appointments) {
	    if (appt.getReport() != null) {
		if (appt.getReport().getVitalSigns() != null) {
		    appt.getDay();
		    GregorianCalendar gc = new GregorianCalendar(2011, 0, 1);
		    gc.roll(Calendar.DAY_OF_YEAR, appt.getDay());
		    StringBuilder builder = new StringBuilder();
		    builder.append(CalendarPanel.getMonthMap().get(
			    gc.get(Calendar.MONTH)));
		    builder.append(" ");
		    builder.append(gc.get(Calendar.DAY_OF_MONTH));
		    builder.append(", ");
		    builder.append(gc.get(Calendar.YEAR));
		    dataset.addValue(appt.getReport().getVitalSigns()
			    .getWeight(), series1, builder.toString());
		}
	    }
	}
	return dataset;

    }

    /**
     * @param dataset
     * @return
     */
    private JFreeChart createChart(final CategoryDataset dataset) {

	final JFreeChart chart = ChartFactory.createLineChart(
		"Weight over Time", "Date", "Weight", dataset,
		PlotOrientation.VERTICAL, true, true, false);

	chart.setBackgroundPaint(Color.white);

	final CategoryPlot plot = (CategoryPlot) chart.getPlot();
	plot.setBackgroundPaint(Color.lightGray);
	plot.setRangeGridlinePaint(Color.white);

	final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
	rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
	rangeAxis.setAutoRangeIncludesZero(true);

	final LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot
		.getRenderer();

	renderer.setSeriesStroke(0, new BasicStroke(2.0f,
		BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 1.0f,
		new float[] { 10.0f, 6.0f }, 0.0f));

	return chart;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
	if(e.getSource() == getCloseButton()){
	    this.setVisible(false);
	}
    }

}
